package com.metroinfo.workers;

import java.io.*;
import java.nio.*;

import com.metroinfo.infrastructure.MainDataStructure;
import com.metroinfo.kernel.ProcessData;
import com.metroinfo.kernel.data.ResponseData;
import com.metroinfo.parser.CommandParser;
import com.metroinfo.parser.GeneralSettings;
import com.metroinfo.parser.data.GeneralRequest;

/**
 * Primary driver class used by blocking Servers to receive, prepare, send, and
 * shutdown requests.
 * 
 * @author Mark Reinhold
 * @author Brad R. Wetmore
 * @version 1.4, 10/01/12
 */
public class RequestServicer implements Runnable {

	private ChannelIO cio;
	private MainDataStructure mainDataStructure;

	public RequestServicer(ChannelIO cio, MainDataStructure mds) {
		this.cio = cio;
		this.mainDataStructure = mds;
	}

	private void service() throws IOException {
		try {
			ByteBuffer rbb = receive(); // Receive
			CommandParser comParser = new CommandParser();
			GeneralRequest generalReq = comParser.getData(rbb);
			
			ProcessData processData = new ProcessData(mainDataStructure);
			ResponseData responseData = processData.process(generalReq);
			
			switch (generalReq.getReqType()){
			case(GeneralSettings.CT_SEND_DATA):
				cio.write(responseData.getResponse());
				break;
			default:
				break;
			}
		
			cio.close();
			cio.shutdown();
		
		} catch (IOException x) {
			String m = x.getMessage();
			if (!m.equals("Broken pipe")
					&& !m.equals("Connection reset by peer")) {
				System.err.println("RequestHandler: " + x.toString());
			}

			try {
				cio.shutdown();
			} catch (IOException e) {
			}

			cio.close();
		}
	}

	public void run() {
		try {
			service();
		} catch (IOException x) {
			x.printStackTrace();
		}
	}

	ByteBuffer receive() throws IOException {

		for (;;) {
			int read = cio.read();
			ByteBuffer bb = cio.getReadBuf();
			if (read < 0 || isReceived(bb) ) {
				bb.flip();
				return bb;
			}
		}
	}
	private boolean isReceived(ByteBuffer bb){
		return bb.get(bb.position())==0;
	
	}
}
